import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Params } from '@angular/router';
import { AfMessageService, AfNavigationService, AfDateService } from '@core';
import { differenceInCalendarDays, setHours } from 'date-fns';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzTreeComponent, NzTreeNode } from 'ng-zorro-antd/tree';
import { Observable, catchError, map, zip } from 'rxjs';

import { SecurityService } from '../../security.service';

@Component({
  selector: 'app-security-role-edit',
  styleUrls: ['./edit.component.less'],
  templateUrl: './edit.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SecurityRoleEditComponent implements OnInit {
  @ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;

  form!: UntypedFormGroup;
  submitting = false;
  saveError = null;

  constructor(
    private fb: UntypedFormBuilder,
    private msg: NzMessageService,
    private securitySrv: SecurityService,
    private cdr: ChangeDetectorRef,
    private msgSrv: AfMessageService,
    private navSrv: AfNavigationService,
    private dateSrv: AfDateService
  ) {}

  editParam!: Params;
  record: any;
  btn: any = 'add';
  ngOnInit(): void {
    this.form = this.fb.group({
      id: ['', []],
      name: ['', [Validators.required]],
      descr: ['', []],
      role: ['', [Validators.required]]
    });

    this.editParam = this.navSrv.getQueryParam();
    this.btn = this.editParam['btn'];
    this.record = JSON.parse(this.editParam['record']);

    this.initData(this.record.id).subscribe(res => {
      this.initFormValue();
    });

    this.cdr.detectChanges();
  }

  menuTree: any[] = [];
  defaultMenus: any[] = [];
  initData(id: any): Observable<void> {
    return zip(this.securitySrv.queryMenuTree(), this.securitySrv.queryMenuIdByRole(id)).pipe(
      // 接收其他拦截器后产生的异常消息
      catchError(res => {
        console.warn(`StartupService.load: Network request failed`, res);
        // setTimeout(() => this.router.navigateByUrl(`/exception/500`));
        return [];
      }),
      map(([allMenuResult, selectedMenuResult]: [NzSafeAny, NzSafeAny]) => {
        if (allMenuResult.status) {
          this.menuTree = allMenuResult.data;
        }
        if (selectedMenuResult.status) {
          this.defaultMenus = selectedMenuResult.data;
        }
      })
    );
  }

  selectedIndex = 0;
  treeTitle: any = '添加菜单';
  initFormValue() {
    this.selectedIndex = this.editParam['index'];
    if (this.btn == 'edit') {
      this.treeTitle = `为"${this.record.name}"角色，添加菜单`;
      this.form.patchValue(this.record);
    }
  }

  submit(): void {
    const body = this.form.getRawValue();

    this.submitting = true;
    this.securitySrv.saveRole(body).subscribe(res => {
      if (res.status) {
        this.form.controls['id'].setValue(res.data);
        this.msgSrv.msg_success(`提交成功`);
      } else {
        this.msgSrv.msg_warning(`${res.msg}`);
      }
    });

    setTimeout(() => {
      this.submitting = false;
      this.cdr.detectChanges();
    }, 1000);
  }

  today = new Date();
  disabledDate = (current: Date): boolean => {
    return differenceInCalendarDays(current, this.today) < 0;
  };

  checkIds: any[] = [];
  pushChildrenIds(checkedNodes: NzTreeNode[]) {
    checkedNodes.forEach((item: NzTreeNode) => {
      this.checkIds.push((item.origin as any).id);
      if (item.children && item.children.length >= 1) {
        this.pushChildrenIds(item.children);
      }
    });
  }

  pushParentIds(checkedNodes: NzTreeNode[]) {
    checkedNodes.forEach((item: NzTreeNode) => {
      this.pushParentId(item);
    });
  }

  pushParentId(node: NzTreeNode) {
    if (node.parentNode) {
      this.checkIds.push((node.parentNode.origin as any).id);
      this.pushParentId(node.parentNode);
    }
  }

  grantMenu() {
    if (this.form.controls['id'].value == null || this.form.controls['id'].value == '') {
      this.msgSrv.msg_error('请先提交角色后，才能提交菜单');
      return;
    }

    this.checkIds = [];
    const checkedNodes: NzTreeNode[] = this.nzTreeComponent.getCheckedNodeList();
    console.log(checkedNodes);
    if (checkedNodes && checkedNodes.length >= 1) {
      this.pushParentIds(checkedNodes);
      this.pushChildrenIds(checkedNodes);
    }
    console.log(this.checkIds);
    this.securitySrv.saveRoleMenus(this.form.controls['id'].value, this.checkIds).subscribe(res => {
      if (res.status) {
        this.msgSrv.msg_success(`菜单分配成功`);
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }

  back() {
    this.navSrv.navigateByUrl('/security/role/list');
  }

  checkOptionsOne = [
    { label: 'Apple', value: 'Apple', checked: true },
    { label: 'Pear', value: 'Pear', checked: false },
    { label: 'Orange', value: 'Orange', checked: false }
  ];
}
